package turtle.system.pt;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import turtle.system.pt.Bar;
import turtle.system.pt.BarSet;
import turtle.system.pt.DailyStopProfitExec;
import turtle.system.pt.MDD;
import turtle.system.pt.PriceData;
import turtle.system.pt.StatCalc;

public class PriceDataStopProfit {
	public static final int STRATEGY_CONSERVATIVE = 1;
	public static final int STRATEGY_POSITIVE = 2;
	public static final String CONS_FN = "data/conservative_my.log";
	public static final String POSI_FN = "data/positive_my.log";
	public String finalSuggestion = null;
	public String summary = null;
	private BufferedWriter writer;
	private static Logger DEFAULT_LOGGER = loadDefaultLogger();
	public Logger logger = DEFAULT_LOGGER;

	// private static String DATA_PATH = "data/";

	// private static String FILENAME_SUFFIX = ".txt";
	private static boolean IS_GENERATE_GRID_CSV = false; // 產生累積獲利 CSV 檔 // 約需執行
	private static boolean IS_PRINT_TURTLE_ACTION = true; // 印出每筆進出場記錄
	private static boolean IS_PRINT_TURTLE_SUMMARY = true; // 印出累積獲利摘要統計
	// private static boolean IS_PRINT_TURTLE_ACTION = false; // 印出每筆進出場記錄

	// 5 分鐘
	// private static boolean IS_GENERATE_GRID_CSV = true; // 產生累積獲利 CSV 檔 //
	// 約需執行 5 分鐘
	/**
	 * 系統強制平倉點數
	 */
	public static int FORCE_STOPLOSS = 100000;
	private static int SCALE_DOWN_FACTOR = 100; // 獲利 CSV 檔中數值除以此常數，方便作圖
	// private static int[] LOSS_STOP_RANGE_FOR_LONG = {27,27}; // 做多停損點數實驗區間
	// private static int[] LOSS_STOP_RANGE_FOR_LONG = { 10, 90 }; // 做多停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_LONG = null;
	public static int[] LOSS_STOP_RANGE_FOR_LONG_CONSERVATIVE = { 40, 40 }; // 做多停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_LONG_POSITIVE = { 10000, 10000 }; // 做多停損點數實驗區間

	public static int[] PROFIT_STOP_RANGE_FOR_LONG = null;
	public static int[] PROFIT_STOP_RANGE_FOR_LONG_CONSERVATIVE = { 250, 250 }; // 做多停利點數實驗區間
	public static int[] PROFIT_STOP_RANGE_FOR_LONG_POSITIVE = { 10000, 10000 }; // 做多停利點數實驗區間

	// private static int[] LOSS_STOP_RANGE_FOR_SHORT = {27,27}; // 做空停損點數實驗區間
	// private static int[] LOSS_STOP_RANGE_FOR_SHORT = { 10, 90 }; //
	// 做空停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_SHORT = null;
	public static int[] LOSS_STOP_RANGE_FOR_SHORT_CONSERVATIVE = { 40, 40 }; // 做空停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_SHORT_POSITIVE = { 10000, 10000 }; // 做空停損點數實驗區間

	public static int[] PROFIT_STOP_RANGE_FOR_SHORT = null;
	public static int[] PROFIT_STOP_RANGE_FOR_SHORT_CONSERVATIVE = { 150, 150 }; // 做空停利點數實驗區間
	public static int[] PROFIT_STOP_RANGE_FOR_SHORT_POSITIVE = { 10000, 10000 }; // 做空停利點數實驗區間
	public int numOutStopProfit = 0, numOutStopLoss = 0,
	numOutTrendReverse = 0, numOutForceStopLoss = 0;
	// int minDaysIn = 1, maxDaysIn = 100, minDaysOut = 1, maxDaysOut = 100;
	private static int minDaysInForLong = 2, maxDaysInForLong = 3,
			minDaysOutForLong = 2, maxDaysOutForLong = 3;
	private static int minDaysInForShort = 2, maxDaysInForShort = 3,
			minDaysOutForShort = 2, maxDaysOutForShort = 3;

	public static int[][] inAndOut = null;
	public static int[][] inAndOut_CONSERVATIVE = new int[][] { // 特別觀察組合
	// { 3, 16, 15, 22 } // 保守穩健系統
	// { 2, 7, 2, 4 }
	{ 2, 8, 2, 12 }

	};
	public static int[][] inAndOut_POSITIVE = new int[][] { // 特別觀察組合
	// { 9, 21, 3, 5 } // 積極進取系統
	{ 35, 21, 2, 16 } // 不停損停利的最佳參數(無盤中出場)
	//{ 8, 4, 2, 5}
	// { 2, 7, 2, 6 }
	};

	public String getFinalSuggestion() {
		return finalSuggestion;
	}

	public String getSummary() {
		return summary;
	}

	public PriceDataStopProfit(int strategyType, String BASE_FILENAME,
			String TX_FILENAME) throws IOException {
		if (strategyType == STRATEGY_POSITIVE) {
			LOSS_STOP_RANGE_FOR_LONG = LOSS_STOP_RANGE_FOR_LONG_POSITIVE;
			LOSS_STOP_RANGE_FOR_SHORT = LOSS_STOP_RANGE_FOR_SHORT_POSITIVE;
			inAndOut = inAndOut_POSITIVE;
			PROFIT_STOP_RANGE_FOR_LONG = PROFIT_STOP_RANGE_FOR_LONG_POSITIVE;
			PROFIT_STOP_RANGE_FOR_SHORT = PROFIT_STOP_RANGE_FOR_SHORT_POSITIVE;
			writer = new BufferedWriter(new FileWriter(POSI_FN));
		} else {
			LOSS_STOP_RANGE_FOR_LONG = LOSS_STOP_RANGE_FOR_LONG_CONSERVATIVE;
			LOSS_STOP_RANGE_FOR_SHORT = LOSS_STOP_RANGE_FOR_SHORT_CONSERVATIVE;
			inAndOut = inAndOut_CONSERVATIVE;
			PROFIT_STOP_RANGE_FOR_LONG = PROFIT_STOP_RANGE_FOR_LONG_CONSERVATIVE;
			PROFIT_STOP_RANGE_FOR_SHORT = PROFIT_STOP_RANGE_FOR_SHORT_CONSERVATIVE;
			writer = new BufferedWriter(new FileWriter(CONS_FN));
		}

		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		Date today = GregorianCalendar.getInstance().getTime();

		long startTime = System.currentTimeMillis();

		String filename = BASE_FILENAME;

		FileReader reader = new FileReader(filename);
		BarSet barSet = new BarSet(reader);
		// Chart.draw(barSet);

		String filename2 = TX_FILENAME;
		FileReader reader2 = new FileReader(filename2);
		BarSet barSet2 = new BarSet(reader2);

		// print day records in which range is over 300
		// bigRange(barSet, 300);

		int maxProfitDaysInForLong = 0, maxProfitDaysOutForLong = 0, maxProfitDaysInForShort = 0, maxProfitDaysOutForShort = 0, maxProfitLossStopForLong = LOSS_STOP_RANGE_FOR_LONG[0], maxProfitLossStopForShort = LOSS_STOP_RANGE_FOR_SHORT[0], maxProfitProfitStopForLong = PROFIT_STOP_RANGE_FOR_LONG[0], maxProfitProfitStopForShort = PROFIT_STOP_RANGE_FOR_SHORT[0];
		// csv file for Excel graphing
		if (IS_GENERATE_GRID_CSV) {
			BufferedWriter csvOut = new BufferedWriter(new FileWriter(
					"data/parameter.csv"));
			StringBuilder sb = new StringBuilder();
			StringBuffer buf = new StringBuffer();
			StatCalc scStrategyProfit = new StatCalc(); // 記錄所有進出天數組合的獲利

			int kStep = 7;
			int qStep = 7;
			int oStep = 20;
			int pStep = 20;
			for (int k = LOSS_STOP_RANGE_FOR_LONG[0]; k <= LOSS_STOP_RANGE_FOR_LONG[1]; k += kStep) {
				for (int q = LOSS_STOP_RANGE_FOR_SHORT[0]; q <= LOSS_STOP_RANGE_FOR_SHORT[1]; q += qStep) {
					for (int o = PROFIT_STOP_RANGE_FOR_LONG[0]; o <= PROFIT_STOP_RANGE_FOR_LONG[1]; o += oStep) {
						for (int p = PROFIT_STOP_RANGE_FOR_SHORT[0]; p <= PROFIT_STOP_RANGE_FOR_SHORT[1]; p += pStep) {
							StatCalc stopStrategy = new StatCalc(); // 記錄所有進出天數組合的獲利

							for (int i = minDaysInForLong; i <= maxDaysInForLong; i++) {
								for (int j = minDaysOutForLong; j <= maxDaysOutForLong; j++) {
									for (int m = minDaysInForShort; m <= maxDaysInForShort; m++) {
										for (int n = minDaysOutForShort; n <= maxDaysOutForShort; n++) {

											double profit = turtle(barSet, i,
													j, m, n, k, q, o, p,
													barSet2);
											scStrategyProfit.enter(profit,
													new int[] { i, j, m, n, k,
															q, o, p });
											stopStrategy.enter(profit,
													new int[] { i, j, m, n, k,
															q, o, p });
											// int scaleProfit = (int)(profit /
											// SCALE_DOWN_FACTOR);
											// sb.append(String.format("%d",
											// scaleProfit));
											// if (j != maxDaysOut)
											// sb.append(","); // row end
											// 不加 ,
										}
									}
									System.out.print(".");
								}
							}
							buf
									.append(String
											.format(
													"完成停損%d,%d 停利%d,%d - 最大獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,最小獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,平均獲利=%.2f,正獲利組合數=%d(平均%.2f),負獲利組合數=%d(平均%.2f)",
													k,
													q,
													o,
													p,
													stopStrategy.getMaxParam()[0],
													stopStrategy.getMaxParam()[1],
													stopStrategy.getMaxParam()[2],
													stopStrategy.getMaxParam()[3],
													stopStrategy.getMaxParam()[4],
													stopStrategy.getMaxParam()[5],
													stopStrategy.getMax(),
													stopStrategy.getMinParam()[0],
													stopStrategy.getMinParam()[1],
													stopStrategy.getMinParam()[2],
													stopStrategy.getMinParam()[3],
													stopStrategy.getMinParam()[4],
													stopStrategy.getMinParam()[5],
													stopStrategy.getMin(),
													stopStrategy.getMean(),
													stopStrategy
															.getPositiveCount(),
													stopStrategy
															.getPositiveMean(),
													stopStrategy
															.getNegativeCount(),
													stopStrategy
															.getNegativeMean()));
							System.out.println(buf.toString());
							// 完成停損%d,%d 停利%d,%d -
							// 最大獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,最小獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,平均獲利=%.2f,正獲利組合數=%d(平均%.2f),負獲利組合數=%d(平均%.2f)
							String outStr = k + "," + q + "," + o + "," + p
									+ "," + stopStrategy.getMaxParam()[0] + ","
									+ stopStrategy.getMaxParam()[1] + ","
									+ stopStrategy.getMaxParam()[2] + ","
									+ stopStrategy.getMaxParam()[3] + ","
									+ stopStrategy.getMaxParam()[4] + ","
									+ stopStrategy.getMaxParam()[5] + ","
									+ stopStrategy.getMax() + ","
									+ stopStrategy.getMinParam()[0] + ","
									+ stopStrategy.getMinParam()[1] + ","
									+ stopStrategy.getMinParam()[2] + ","
									+ stopStrategy.getMinParam()[3] + ","
									+ stopStrategy.getMinParam()[4] + ","
									+ stopStrategy.getMinParam()[5] + ","
									+ stopStrategy.getMin() + ","
									+ stopStrategy.getMean() + ","
									+ stopStrategy.getPositiveCount() + ","
									+ stopStrategy.getPositiveMean() + ","
									+ stopStrategy.getNegativeCount() + ","
									+ stopStrategy.getNegativeMean();
							csvOut.write(outStr + "\n");
							csvOut.flush();
							buf = new StringBuffer();
						}
						// sb.append("\n");
					}
				}
			}
			csvOut.close();
			System.out
					.println(String
							.format(
									"最大獲利組合(做多%d,%d)(做空%d,%d)[停損%d,%d][停利%d,%d]=%.2f,"
											+ "最小獲利組合(做多%d,%d)(做空%d,%d)[停損%d,%d][停利%d,%d]=%.2f,"
											+ "平均獲利=%.2f,正獲利組合數=%d(平均%.2f),負獲利組合數=%d(平均%.2f)",
									scStrategyProfit.getMaxParam()[0],
									scStrategyProfit.getMaxParam()[1],
									scStrategyProfit.getMaxParam()[2],
									scStrategyProfit.getMaxParam()[3],
									scStrategyProfit.getMaxParam()[4],
									scStrategyProfit.getMaxParam()[5],
									scStrategyProfit.getMaxParam()[6],
									scStrategyProfit.getMaxParam()[7],
									scStrategyProfit.getMax(), scStrategyProfit
											.getMinParam()[0], scStrategyProfit
											.getMinParam()[1], scStrategyProfit
											.getMinParam()[2], scStrategyProfit
											.getMinParam()[3], scStrategyProfit
											.getMinParam()[4], scStrategyProfit
											.getMinParam()[5], scStrategyProfit
											.getMinParam()[6], scStrategyProfit
											.getMinParam()[7], scStrategyProfit
											.getMin(), scStrategyProfit
											.getMean(), scStrategyProfit
											.getPositiveCount(),
									scStrategyProfit.getPositiveMean(),
									scStrategyProfit.getNegativeCount(),
									scStrategyProfit.getNegativeMean()));

			maxProfitDaysInForLong = scStrategyProfit.getMaxParam()[0];
			maxProfitDaysOutForLong = scStrategyProfit.getMaxParam()[1];
			maxProfitLossStopForLong = scStrategyProfit.getMaxParam()[2];
			maxProfitLossStopForShort = scStrategyProfit.getMaxParam()[3];
		}

		System.out.println("");
		for (int[] ia : inAndOut) {
			turtle(barSet, ia[0], ia[1], ia[2], ia[3],
					maxProfitLossStopForLong, maxProfitLossStopForShort,
					maxProfitProfitStopForLong, maxProfitProfitStopForShort,
					barSet2);
			System.out.println("");
		}

		// 重新 print 一次最大獲利組合
		/*
		 * if (IS_GENERATE_GRID_CSV) { turtle(barSet, maxProfitDaysInForLong,
		 * maxProfitDaysOutForLong, maxProfitDaysInForShort,
		 * maxProfitDaysOutForShort, maxProfitLossStopForLong,
		 * maxProfitLossStopForShort, maxProfitProfitStopForLong,
		 * maxProfitProfitStopForShort, barSet2); }
		 */
		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis() - startTime;
		System.out.println(String.format("執行時間: %.2f 秒",
				elapsedTimeMillis / 1000F));
		writer.close();

	}

	public static void copyFile(String srcFN, String destFN) {
		try {
			File inputFile = new File(srcFN);
			File outputFile = new File(destFN);

			FileReader in = new FileReader(inputFile);
			FileWriter out = new FileWriter(outputFile);
			int c;

			while ((c = in.read()) != -1)
				out.write(c);

			in.close();
			out.close();
		} catch (IOException e) {
			System.out.println(e);
		}
	}

	public static void bigRange(BarSet barSet, int howBig) {
		ListIterator<Bar> it = barSet.iter();
		int barCountTotal = 0;
		int barCountMatch = 0;
		while (it.hasNext()) {
			Bar bar = it.next();
			barCountTotal++;
			if (bar.range > howBig) {
				System.out.println(bar);
				barCountMatch++;
			}
		}
		System.out.println(String.format("%d out of %d match the criteria",
				barCountMatch, barCountTotal));
	}

	private static int highestIndex(List<Double> list) {
		int ret = 0;
		Iterator<Double> iter = list.iterator();
		double highest = Double.MIN_VALUE;
		int currentIndex = 0;
		while (iter.hasNext()) {
			double currentValue = iter.next();
			if (currentValue > highest) {
				highest = currentValue;
				ret = currentIndex;
			}
			currentIndex++;
		}
		return ret;
	}

	private static int lowestIndex(List<Double> list) {
		int ret = 0;
		Iterator<Double> iter = list.iterator();
		double lowest = Double.MAX_VALUE;
		int currentIndex = 0;
		while (iter.hasNext()) {
			double currentValue = iter.next();
			if (currentValue < lowest) {
				lowest = currentValue;
				ret = currentIndex;
			}
			currentIndex++;
		}
		return ret;
	}

	private String printTurtleAction(Bar bar, boolean inHand, boolean bull,
			double baseOrProfit, int daysInOrOut, boolean stopLoss,
			int lossStop, boolean stopProfit, int profitStop, boolean forceOut,
			double liquidPrice, Bar bar2, Bar breakBar2) {
		if (!IS_PRINT_TURTLE_ACTION)
			return null;
		StringBuffer buf = new StringBuffer();

		buf.append(bar.mergeBar(bar2) + "\n");
		if (forceOut) {
			if (baseOrProfit == - FORCE_STOPLOSS) {
			  buf.append("出場, 出場價 " + String.format("%.0f", liquidPrice) + ", 理由："
					+ "盤中強制停損出場,");
			}
			else {
				buf.append("出場, 出場價 " + String.format("%.0f", liquidPrice) + ", 理由："
						+ "盤中開盤強制停損出場,");				
			}
		} else {
			buf
					.append((inHand ? "進場" : ("出場, 出場價 " + String.format(
							"%.0f", liquidPrice)))
							+ ", 理由："
							+ ((stopLoss | stopProfit) ? ((stopLoss) ? ("停損"
									+ lossStop + " 點    ")
									: ("停利" + profitStop + " 點    "))
									: ("前一日創 " + daysInOrOut + " 天新" + (inHand
											^ bull ? "低" : "高"))) + ", ");
		}
		buf.append(String.format("前一日大盤[%.0f-%.0f-%.0f-%.0f-d=%.0f], ",
				breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
				breakBar2.diff));
		if (inHand) {
			buf.append("做" + (bull ? "多" : "空") + ", 進場價 "
					+ String.format("%.0f", baseOrProfit));
		} else {
			buf
					.append("獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
							+ String.format("%.0f", baseOrProfit) + "] * *");
		}
		try {
			writer.write(buf.toString() + "\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.info(buf.toString());
		/*
		 * logger.info(bar.mergeBar(bar2)); buf.append(bar.mergeBar(bar2));
		 * logger.info ((inHand ? "進場" : ("出場, 出場價 " + String.format("%.0f",
		 * liquidPrice))) + ", 理由：" + (stopLoss ? ("停損 " + lossStop + " 點    ")
		 * : ("前一日創 " + daysInOrOut + " 天新" + (inHand ^ bull ? "低" : "高"))) +
		 * ", "); buf.append((inHand ? "進場" : ("出場, 出場價 " +
		 * String.format("%.0f", liquidPrice))) + ", 理由：" + (stopLoss ? ("停損 " +
		 * lossStop + " 點    ") : ("前一日創 " + daysInOrOut + " 天新" + (inHand ^
		 * bull ? "低" : "高"))) + ", ");
		 * logger.info(String.format("前一日[%.0f,%.0f,%.0f,%.0f,d=%.0f], ",
		 * breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
		 * breakBar2.diff));
		 * buf.append(String.format("前一日[%.0f,%.0f,%.0f,%.0f,d=%.0f], ",
		 * breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
		 * breakBar2.diff)); if (inHand) { logger.info("做" + (bull ? "多" : "空")
		 * + ", 進場價 " + String.format("%.0f", baseOrProfit)); buf.append("做" +
		 * (bull ? "多" : "空") + ", 進場價 " + String.format("%.0f", baseOrProfit));
		 * } else {logger.info(
		 * "獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
		 * + String.format("%.0f", baseOrProfit) + "] * *");buf.append(
		 * "獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
		 * + String.format("%.0f", baseOrProfit) + "] * *"); }
		 */
		System.out.println("=======================================");
		finalSuggestion = buf.toString();
		return buf.toString();
	}

	private static int diffCalendarDays(Bar current, Bar base) {
		long diffMillis = current.today.getTimeInMillis()
				- base.today.getTimeInMillis();
		return (int) (diffMillis / (24 * 60 * 60 * 1000));
	}

	StatCalc thisProfit = null;

	public void setProfitStat(StatCalc prof) {
		this.thisProfit = prof;
	}

	public StatCalc getProfitStat() {
		return thisProfit;
	}

	double thisAcc = -1;

	public void setAcc(double acc) {
		this.thisAcc = acc;
	}

	public double getAcc() {
		return this.thisAcc;
	}

	MDD thisMDD = null;

	public void setMDD(MDD mdd) {
		this.thisMDD = mdd;
	}

	public MDD getMDD() {
		return this.thisMDD;
	}

	/**
	 * 強制平倉出場
	 */
	public boolean performInstantlyForceOut(Bar bar2, double basePrice2,
			boolean bull) {

		boolean forceOut = false;
		if (bar2.high >= basePrice2 + FORCE_STOPLOSS // 強制盤中停損
				&& !bull) { // 手上持有 short position
			forceOut = true;
		} else if (bar2.low <= basePrice2 - FORCE_STOPLOSS // 強制盤中停損
				&& bull) { // 手上持有 多單
			forceOut = true;
		}
		return forceOut;
	}

	public double turtle(BarSet barSet, int daysInForLong, int daysOutForLong,
			int daysInForShort, int daysOutForShort, int lossStopForLong,
			int lossStopForShort, int profitStopForLong,
			int profitStopForShort, BarSet barSet2) {

		StatCalc stopLossStat = new StatCalc();
		StatCalc stopProfitStat = new StatCalc();
		StatCalc stopTrendReverseStat = new StatCalc();
		StatCalc stopForceStopLossStat = new StatCalc();
		StatCalc stopLossOpenCloseStat = new StatCalc();
		StatCalc stopProfitOpenCloseStat = new StatCalc();
		HashMap<String, Integer> tradeMap = new HashMap<String, Integer>();
		String prevTrade = null;
		ListIterator<Bar> it = barSet.iter();
		ListIterator<Bar> it2 = barSet2.iter();
		Bar baseBar = null;
		int baseBarIndex = 0;
		StatCalc scHoldCalendarDays = new StatCalc();
		StatCalc scHoldTransactionDays = new StatCalc();
		StatCalc scProfit = new StatCalc();
		StatCalc scProfitLongDayTrade = new StatCalc();
		StatCalc scProfitShortDayTrade = new StatCalc();
		StatCalc scProfitLongCloseDayTrade = new StatCalc();
		StatCalc scProfitShortCloseDayTrade = new StatCalc();
		StatCalc scProfitLong = new StatCalc();
		StatCalc scProfitShort = new StatCalc();
		StatCalc maxDrawDown = new StatCalc();

		boolean inHand = false;
		boolean bull = false;
		double basePrice = 0.0;
		double basePrice2 = 0.0;
		double accuProfit = 0.0;
		boolean forceOut = false;

		LinkedList<Double> listHighInForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估進場點(做多)
		LinkedList<Double> listLowInForLong = new LinkedList<Double>(); // 以各
		// day
		// bar 的
		// low
		// 組成的
		// list，用以評估進場點(做多)
		LinkedList<Double> listHighOutForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估出場點(做多)
		LinkedList<Double> listLowOutForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// low
		// 組成的
		// list，用以評估出場點(做多)
		LinkedList<Double> listCloseInForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估進場點(做多)
		LinkedList<Double> listCloseOutForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估出場點(做多)

		LinkedList<Double> listHighInForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估進場點(做空)
		LinkedList<Double> listLowInForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// low
		// 組成的
		// list，用以評估進場點(做空)
		LinkedList<Double> listHighOutForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估出場點(做空)
		LinkedList<Double> listLowOutForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// low
		// 組成的
		// list，用以評估出場點(做空)
		LinkedList<Double> listCloseInForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估進場點(做空)
		LinkedList<Double> listCloseOutForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估出場點(做空)
		Bar bar = null;
		Bar bar2 = null;
		while (it.hasNext()) {

			if (forceOut) { // 強制斷頭出場則不必讀取下一筆,因為資料己被讀取過
				forceOut = false;
			} else {
				/* 取得新一天的資料 */
				bar = it.next();
				bar2 = it2.next();
				/* 更新進場點資料 window (做多) */
				if (listHighInForLong.size() == daysInForLong) {
					listHighInForLong.removeFirst();
				}
				if (listLowInForLong.size() == daysInForLong) {
					listLowInForLong.removeFirst();
				}
				if (listCloseInForLong.size() == daysInForLong) {
					listCloseInForLong.removeFirst();
				}
				listHighInForLong.add(bar.high);
				listLowInForLong.add(bar.low);
				listCloseInForLong.add(bar.close);

				/* 更新進場點資料 window (做空) */
				if (listHighInForShort.size() == daysInForShort) {
					listHighInForShort.removeFirst();
				}
				if (listLowInForShort.size() == daysInForShort) {
					listLowInForShort.removeFirst();
				}
				if (listCloseInForShort.size() == daysInForShort) {
					listCloseInForShort.removeFirst();
				}
				listHighInForShort.add(bar.high);
				listLowInForShort.add(bar.low);
				listCloseInForShort.add(bar.close);

				/* 更新出場點資料 window (做多) */
				if (listHighOutForLong.size() == daysOutForLong) {
					listHighOutForLong.removeFirst();
				}
				if (listLowOutForLong.size() == daysOutForLong) {
					listLowOutForLong.removeFirst();
				}
				if (listCloseOutForLong.size() == daysOutForLong) {
					listCloseOutForLong.removeFirst();
				}
				listHighOutForLong.add(bar.high);
				listLowOutForLong.add(bar.low);
				listCloseOutForLong.add(bar.close);

				/* 更新出場點資料 window (做空) */
				if (listHighOutForShort.size() == daysOutForShort) {
					listHighOutForShort.removeFirst();
				}
				if (listLowOutForShort.size() == daysOutForShort) {
					listLowOutForShort.removeFirst();
				}
				if (listCloseOutForShort.size() == daysOutForShort) {
					listCloseOutForShort.removeFirst();
				}
				listHighOutForShort.add(bar.high);
				listLowOutForShort.add(bar.low);
				listCloseOutForShort.add(bar.close);
			}
			if (!inHand) { // 目前空手
				if ((listLowInForShort.size() == daysInForShort && lowestIndex(listLowInForShort) == daysInForShort - 1)
						&& (listHighInForLong.size() == daysInForLong && highestIndex(listHighInForLong) == daysInForLong - 1)) { // 盤中
					// 創
					// daysInForShort
					// 天新低且創
					// daysInForLong
					// 天新高(盤中雙向突破）
					// do nothing, 不進場
				} else if (listLowInForShort.size() == daysInForShort
				// && lowestIndex(listHighInForShort) == daysInForShort - 1 //
						// day bar 的 high 創 daysInForShort 天新低
						&& lowestIndex(listLowInForShort) == daysInForShort - 1 // day
				// bar
				// 的
				// low
				// 創
				// daysInForShort
				// 天新低
				// ******
				// 略勝
				// && lowestIndex(listCloseInForShort) == daysInForShort - 1 //
				// day bar 的 close 創 daysInForShort 天新低
				) {
					inHand = true; // (空單)進場
					bull = false; // 建立 short position
					if (prevTrade != null) {
						String d = "空單進場,前單為" + prevTrade;
						if (tradeMap.containsKey(d)) {
							tradeMap.put(d, tradeMap.get(d) + 1);
						} else {
							tradeMap.put(d, 1);
						}
					}
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題

					Bar nextBar = barSet.getBar(nextIndex); // 交易 DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 1);

					basePrice = nextBar.open; // 假設隔天開盤價成交
					// basePrice = nextBar.close; // 假設隔天收盤價成交
					basePrice2 = nextBar2.open; // 假設隔天開盤價成交
					// basePrice2 = nextBar2.close; // 假設隔天開盤價成交

					// double temp = nextBar.open - nextBar.close; //
					// 做空訊號指示進場當天，開盤加倍放空，收盤回補一半，留倉正常風險量，持續做空****** 賺很多
					double temp2 = nextBar2.open - nextBar2.close;
					// accuProfit += temp;
					accuProfit += temp2;
					// scProfitShortDayTrade.enter(temp);
					scProfitShortDayTrade.enter(temp2);

					baseBar = nextBar;
					baseBarIndex = it.nextIndex();
					// printTurtleAction(nextBar, inHand, bull, basePrice,
					// daysIn, false, 0, 0);
					printTurtleAction(nextBar, inHand, bull, basePrice2,
							daysInForShort, false, 0, false, -1, forceOut, 0,
							nextBar2, breakBar2);
				} else if (listHighInForLong.size() == daysInForLong
				// && highestIndex(listHighInForLong) == daysInForLong - 1 //
						// day bar 的 high 創 daysInForLong 天新高
						&& highestIndex(listLowInForLong) == daysInForLong - 1 // day
				// bar
				// 的
				// low
				// 創
				// daysInForLong
				// 天新高
				// && highestIndex(listCloseInForLong) == daysInForLong - 1 //
				// day bar 的 close 創 daysInForLong 天新高
				) {
					inHand = true; // 進場
					bull = true; // 建立 long position
					if (prevTrade != null) {
						String d = "多單進場,前單為" + prevTrade;
						if (tradeMap.containsKey(d)) {
							tradeMap.put(d, tradeMap.get(d) + 1);
						} else {
							tradeMap.put(d, 1);
						}
					}
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題

					Bar nextBar = barSet.getBar(nextIndex); // 交易 DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 1);

					// basePrice = nextBar.open; // 假設隔天開盤價成交 // 判斷進出場價
					basePrice = nextBar.close; // 假設隔天收盤價成交 // 判斷進出場價
					// basePrice2 = nextBar2.close; // 假設隔天收盤價成交 // 實際操作價
					basePrice2 = nextBar2.open; // 假設隔天收盤價成交 // 實際操作價

					// double temp = nextBar.open - nextBar.close; //
					// 做多訊號指示進場當天，開盤放空，收盤回補，並做多 *************** 賺不多，但逾 5 成勝率
					double temp2 = nextBar2.open - nextBar2.close; // 做多訊號指示進場當天，開盤放空，收盤回補，並做多
					// ***************
					// 用期貨做會賠錢……
					// accuProfit += temp;
					accuProfit += temp2;
					// scProfitLongDayTrade.enter(temp);
					scProfitLongDayTrade.enter(temp2);

					baseBar = nextBar;
					baseBarIndex = it.nextIndex();
					// printTurtleAction(nextBar, inHand, bull, basePrice,
					// daysIn, false, 0, 0);
					printTurtleAction(nextBar, inHand, bull, basePrice2,
							daysInForLong, false, 0, false, -1, forceOut, 0,
							nextBar2, breakBar2);
				}
			} else { // 目前手上有部位
				if (bar2.high >= basePrice2 + FORCE_STOPLOSS // 強制盤中停損
						&& !bull) { // 手上持有 short position
					forceOut = true;
					inHand = false; // 出場
					this.numOutForceStopLoss++;
					prevTrade = "空單,強制盤中停損出場";
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
					double liquidatePrice2 = basePrice2 + FORCE_STOPLOSS;

					/**
					 * 開盤就要被強迫平倉了
					 */
					if (bar2.open >=basePrice2 + FORCE_STOPLOSS) {
						liquidatePrice2 = bar2.open;						
					}
					Bar nextBar = barSet.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 2);

					double profit2 = basePrice2-liquidatePrice2; // 計算獲利
					// accuProfit += profit;
					accuProfit += profit2;
					// scProfit.enter(profit);
					scProfit.enter(profit2);
					stopForceStopLossStat.enter(profit2);
					// scProfitShort.enter(profit);
					scProfitShort.enter(profit2);

					if (IS_PRINT_TURTLE_SUMMARY) {
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
					}

					// printTurtleAction(nextBar, inHand, bull, profit, daysOut,
					// true, lossStopForShort, liquidatePrice);
					printTurtleAction(nextBar, inHand, bull, profit2,
							daysOutForShort, false, -1, true,
							profitStopForShort, forceOut, liquidatePrice2,
							nextBar2, breakBar2);
				} else if (bar2.low <= basePrice2 - FORCE_STOPLOSS // 強制盤中停損
						&& bull) { // 手上持有 多單
					forceOut = true;
					inHand = false; // 出場
					this.numOutForceStopLoss++;
					prevTrade = "多單,強制盤中停損出場";
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
					double liquidatePrice2 = basePrice2 - FORCE_STOPLOSS;
					/**
					 * 開盤就要被強迫平倉了
					 */
					if (bar2.open <=basePrice2 - FORCE_STOPLOSS) {
						liquidatePrice2 = bar2.open;
					}
					Bar nextBar = barSet.getBar(nextIndex - 1); // 交易
																// DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 2);

					double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
					// accuProfit += profit;
					accuProfit += profit2;
					// scProfit.enter(profit);
					scProfit.enter(profit2);
					stopForceStopLossStat.enter(profit2);
					// scProfitShort.enter(profit);
					scProfitShort.enter(profit2);

					if (IS_PRINT_TURTLE_SUMMARY) {
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
					}

					// printTurtleAction(nextBar, inHand, bull, profit, daysOut,
					// true, lossStopForShort, liquidatePrice);
					printTurtleAction(nextBar, inHand, bull, profit2,
							daysOutForShort, false, -1, true,
							profitStopForShort, forceOut, liquidatePrice2,
							nextBar2, breakBar2);
				}

				/* 以下隔天出場條件,都可能在隔天被迫平倉出場 */
				
				else {
					if (it2.nextIndex() == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
					bar2 = barSet2.getBar(it2.nextIndex());
					if (bar2.high >= basePrice2 + FORCE_STOPLOSS // 強制盤中停損
							&& !bull) { // 手上持有 short position
						forceOut = true;
						inHand = false; // 出場
						this.numOutForceStopLoss++;
						prevTrade = "空單,強制盤中停損出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
						double liquidatePrice2 = basePrice2 + FORCE_STOPLOSS;
						/**
						 * 開盤就要被強迫平倉了
						 */
						if (bar2.open >=basePrice2 + FORCE_STOPLOSS) {
							liquidatePrice2 = bar2.open;
						}
						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						double profit2 = basePrice2-liquidatePrice2; // 計算獲利
						// accuProfit += profit;
						accuProfit += profit2;
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						stopForceStopLossStat.enter(profit2);
						// scProfitShort.enter(profit);
						scProfitShort.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						// printTurtleAction(nextBar, inHand, bull, profit, daysOut,
						// true, lossStopForShort, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForShort, false, -1, true,
								profitStopForShort, forceOut, liquidatePrice2,
								nextBar2, breakBar2);
						forceOut = false;
					} else if (bar2.low <= basePrice2 - FORCE_STOPLOSS // 強制盤中停損
							&& bull) { // 手上持有 多單
						forceOut = true;
						inHand = false; // 出場
						this.numOutForceStopLoss++;
						prevTrade = "多單,強制盤中停損出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
						double liquidatePrice2 = basePrice2 - FORCE_STOPLOSS;
						/**
						 * 開盤就要被強迫平倉了
						 */
						if (bar2.open <=basePrice2 - FORCE_STOPLOSS) {
							liquidatePrice2 = bar2.open;
						}
						Bar nextBar = barSet.getBar(nextIndex); // 交易
																	// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						// accuProfit += profit;
						accuProfit += profit2;
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						stopForceStopLossStat.enter(profit2);
						// scProfitShort.enter(profit);
						scProfitShort.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						// printTurtleAction(nextBar, inHand, bull, profit, daysOut,
						// true, lossStopForShort, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForShort, false, -1, true,
								profitStopForShort, forceOut, liquidatePrice2,
								nextBar2, breakBar2);
						forceOut = false;
					}
					
				    else if (listHighOutForShort.size() == daysOutForShort
							&& highestIndex(listHighOutForShort) == daysOutForShort - 1 // day
							// bar
							// 的
							// high
							// 創
							// daysOutForShort
							// 天的
							// high
							// 新高
							// && highestIndex(listCloseOutForShort) ==
							// daysOutForShort - 1 // day bar 的 close 創
							// daysOutForShort 天 的 close 新高
							// && highestIndex(listLowOutForShort) ==
							// daysOutForShort - 1 // day bar 的 low 創
							// daysOutForShort 天 的 low 新高
							&& !bull) { // 手上持有 short position
						inHand = false; // (空單)出場
						this.numOutTrendReverse++;
						prevTrade = "空單,驅勢反轉出場";

						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
										// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
																// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						// double liquidatePrice = nextBar.close; // 不用分損益，都是用
						// close
						// 平倉最好
						// double liquidatePrice2 = nextBar2.close; // 不用分損益，都是用
						// close 平倉最好
						double liquidatePrice2 = nextBar2.open; // 不用分損益，都是用
																// open
						// 平倉最好
						// if (basePrice > bar.high) { // 做空獲利
						// liquidatePrice = nextBar.open; // 假設隔天開盤價成交(空單平倉)
						// -----------------------------------------------------------------
						// } else { // 做空虧損
						// liquidatePrice = nextBar.close; // 假設隔天收盤價成交(空單平倉)
						// }

						// double profit = basePrice - liquidatePrice; // 計算獲利
						double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
						// accuProfit += profit;
						accuProfit += profit2;
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						// scProfitShort.enter(profit);
						scProfitShort.enter(profit2);
						stopTrendReverseStat.enter(profit2);
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
						// printTurtleAction(nextBar, inHand, bull, profit,
						// daysOut,
						// false, 0, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForShort, false, 0, false, -1, forceOut,
								liquidatePrice2, nextBar2, breakBar2);
					} else if (listLowOutForLong.size() == daysOutForLong
							&& lowestIndex(listLowOutForLong) == daysOutForLong - 1 // 創
							// daysOutForLong
							// 天新低
							// && lowestIndex(listHighOutForLong) ==
							// daysOutForLong
							// - 1 // 創 daysOutForLong 天新低
							// && lowestIndex(listCloseOutForLong) ==
							// daysOutForLong
							// - 1 // 創 daysOutForLong 天新低
							// **************** 有機會，試所有天數、停損組合 ******
							&& bull) { // 手上持有 long position
						inHand = false; // 出場
						this.numOutTrendReverse++;
						prevTrade = "多單,驅勢反轉出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
										// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
																// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						double liquidatePrice;
						if (basePrice < bar.low) { // 做多獲利
							liquidatePrice = nextBar.open; // 假設隔天開盤價成交(多單平倉)
						} else { // 做多虧損
							liquidatePrice = nextBar.close; // 假設隔天收盤價成交(多單平倉)
						}

						double liquidatePrice2;
						if (basePrice < bar.low) { // 做多獲利
							// liquidatePrice2 = nextBar2.open; //
							// 假設隔天開盤價成交(多單平倉)
							liquidatePrice2 = nextBar2.close; // 假設隔天開盤價成交(多單平倉)
						} else { // 做多虧損
							// liquidatePrice2 = nextBar2.close; //
							// 假設隔天收盤價成交(多單平倉)
							liquidatePrice2 = nextBar2.open; // 假設隔天收盤價成交(多單平倉)
						}

						// double profit = liquidatePrice - basePrice; // 計算獲利
						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						// accuProfit += profit;
						scProfit.enter(profit2);
						// accuProfit += profit;
						scProfitLong.enter(profit2);
						// accuProfit += profit;
						accuProfit += profit2;
						stopTrendReverseStat.enter(profit2);
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
						// printTurtleAction(nextBar, inHand, bull, profit,
						// daysOut,
						// false, 0, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForLong, false, 0, false, -1, forceOut,
								liquidatePrice2, nextBar2, breakBar2);
					} else if (bar.close >= basePrice + lossStopForShort // 停損
							&& !bull) { // 手上持有 short position = 做空
						inHand = false; // 出場
						this.numOutStopLoss++;
						prevTrade = "空單,停損出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
										// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
																// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						// double liquidatePrice = nextBar.open; //
						// 假設隔天開盤價成交(空單平倉)
						double liquidatePrice = nextBar.close; // 假設隔天收盤價成交(空單平倉)*******
						// 多賺許多
						double liquidatePrice2 = nextBar2.close;
						stopLossOpenCloseStat
								.enter(-(nextBar2.close - nextBar2.open));
						// if (liquidatePrice < basePrice + lossStopForShort) {
						// //
						// 停損出場當天要平倉前變成正獲利，就不平倉了，繼續持有。
						// ****************************************
						// 這要盯收盤，不太符合本程式精神
						// *******************
						// inHand = true;
						// continue;
						// }

						// double temp = nextBar.open - nextBar.close; //
						// *********
						// 停損空單平倉訊號指示出場當天，開盤加碼放空，收盤平倉所有部位 *************** 有賺頭，逾
						// 6
						// 成勝率
						double temp2 = nextBar2.open - nextBar2.close; // *********
						// 停損空單平倉訊號指示出場當天，開盤加碼放空，收盤平倉所有部位
						// ***************
						// 有賺頭，逾 6
						// 成勝率
						// accuProfit += temp;
						accuProfit += temp2;
						// scProfitShortCloseDayTrade.enter(temp);
						scProfitShortCloseDayTrade.enter(temp2);

						// double profit = basePrice - liquidatePrice; // 計算獲利
						double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
						// accuProfit += profit;
						accuProfit += profit2;
						stopLossStat.enter(profit2);
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						// scProfitShort.enter(profit);
						scProfitShort.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						// printTurtleAction(nextBar, inHand, bull, profit,
						// daysOut,
						// true, lossStopForShort, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForShort, true, lossStopForShort, false,
								-1, forceOut, liquidatePrice2, nextBar2,
								breakBar2);

						// if (listHighIn.size() == daysIn
						// && highestIndex(listLowIn) == daysIn - 1 // day bar 的
						// low
						// 創 daysIn
						// 天新高
						// ) {
						// inHand = true; // 進場
						// bull = true; // 建立 long position
						// basePrice = nextBar.close; // 假設隔天收盤價成交
						// baseBar = nextBar;
						// baseBarIndex = it.nextIndex();
						// printTurtleAction(nextBar, inHand, bull, basePrice,
						// daysIn, false,
						// 0, 0);
						// }
					} else if (bar.close <= basePrice - lossStopForLong // 停損
							&& bull) { // 手上持有 long position = 做多
						inHand = false; // 出場
						this.numOutStopLoss++;
						prevTrade = "多單,停損出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
										// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
																// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						// double liquidatePrice = nextBar.open; //
						// 假設隔天開盤價成交(多單平倉)
						// ******
						// 差異不大
						double liquidatePrice = nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = nextBar2.close; // 假設隔天收盤價成交(多單平倉)
						stopLossOpenCloseStat.enter(nextBar2.close
								- nextBar2.open);
						// accuProfit += (nextBar.close - nextBar.open); //
						// *********
						// 停損多單平倉訊號指示出場當天，開盤加碼做多，收盤平倉所有部位 *************** 沒賺頭
						// scProfitLongCloseDayTrade.enter(nextBar.close -
						// nextBar.open);

						accuProfit += (nextBar2.close - nextBar2.open); // *********
						// 停損多單平倉訊號指示出場當天，開盤加碼做多，收盤平倉所有部位 *************** 沒賺頭
						scProfitLongCloseDayTrade.enter(nextBar2.close
								- nextBar2.open);

						// if (liquidatePrice > basePrice - lossStopForLong ) {
						// //
						// 停損出場當天要平倉前變成正獲利，就不平倉了，繼續持有。
						// ****************************************
						// 這要盯收盤，不太符合本程式精神
						// *******************
						// inHand = true;
						// continue;
						// }

						// double profit = liquidatePrice - basePrice; // 計算獲利
						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						// accuProfit += profit;
						accuProfit += profit2;
						stopLossStat.enter(profit2);
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						// scProfitLong.enter(profit);
						scProfitLong.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						// printTurtleAction(nextBar, inHand, bull, profit,
						// daysOut,
						// true, lossStopForLong, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForLong, true, lossStopForLong, false,
								-1, forceOut, liquidatePrice2, nextBar2,
								breakBar2);
					}

					else if (bar.close <= basePrice - profitStopForShort // 停利
							&& !bull) { // 手上持有 short position = 做空
						inHand = false; // 出場
						this.numOutStopProfit++;
						prevTrade = "空單,停利出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
										// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
																// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						// double liquidatePrice = nextBar.open; //
						// 假設隔天開盤價成交(空單平倉)

						// 這要實驗--DOUG
						double liquidatePrice = nextBar.open;
						// double liquidatePrice = nextBar.close; //
						// 假設隔天開盤價成交(空單平倉)*******
						// 多賺許多
						double liquidatePrice2 = nextBar2.open;

						// if (liquidatePrice < basePrice + lossStopForShort) {
						// //
						// 停損出場當天要平倉前變成正獲利，就不平倉了，繼續持有。
						// ****************************************
						// 這要盯收盤，不太符合本程式精神
						// *******************
						// inHand = true;
						// continue;
						// }

						// double temp = nextBar.open - nextBar.close; //
						// *********
						// 停損空單平倉訊號指示出場當天，開盤加碼放空，收盤平倉所有部位 *************** 有賺頭，逾
						// 6
						// 成勝率
						// double temp2 = nextBar2.open - nextBar2.close; //
						// ********* 停損空單平倉訊號指示出場當天，開盤加碼放空，收盤平倉所有部位
						// ***************
						// 有賺頭，逾 6 成勝率
						// accuProfit += temp;
						// accuProfit += temp2;
						// scProfitShortCloseDayTrade.enter(temp);
						// scProfitShortCloseDayTrade.enter(temp2);

						// double profit = basePrice - liquidatePrice; // 計算獲利
						double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
						stopProfitOpenCloseStat
								.enter(-(nextBar2.open - nextBar2.close));
						// accuProfit += profit;
						accuProfit += profit2;
						stopProfitStat.enter(profit2);
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						// scProfitShort.enter(profit);
						scProfitShort.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						// printTurtleAction(nextBar, inHand, bull, profit,
						// daysOut,
						// true, lossStopForShort, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForShort, false, -1, true,
								profitStopForShort, forceOut, liquidatePrice2,
								nextBar2, breakBar2);

						// if (listHighIn.size() == daysIn
						// && highestIndex(listLowIn) == daysIn - 1 // day bar 的
						// low
						// 創 daysIn
						// 天新高
						// ) {
						// inHand = true; // 進場
						// bull = true; // 建立 long position
						// basePrice = nextBar.close; // 假設隔天收盤價成交
						// baseBar = nextBar;
						// baseBarIndex = it.nextIndex();
						// printTurtleAction(nextBar, inHand, bull, basePrice,
						// daysIn, false,
						// 0, 0);
						// }
					} else if (bar.close >= basePrice + profitStopForLong // 停利
							&& bull) { // 手上持有 long position = 做多
						inHand = false; // 出場
						this.numOutStopProfit++;
						prevTrade = "多單,停利出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
										// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
																// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						// double liquidatePrice = nextBar.open; //
						// 假設隔天開盤價成交(多單平倉)
						// ******
						// 差異不大
						// 這要實驗!!
						double liquidatePrice = nextBar.open; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = nextBar2.open; // 假設隔天收盤價成交(多單平倉)

						// accuProfit += (nextBar.close - nextBar.open); //
						// *********
						// 停損多單平倉訊號指示出場當天，開盤加碼做多，收盤平倉所有部位 *************** 沒賺頭
						// scProfitLongCloseDayTrade.enter(nextBar.close -
						// nextBar.open);

						// accuProfit += (nextBar2.close - nextBar2.open); //
						// *********
						// 停損多單平倉訊號指示出場當天，開盤加碼做多，收盤平倉所有部位 *************** 沒賺頭
						// scProfitLongCloseDayTrade.enter(nextBar2.close -
						// nextBar2.open);

						// if (liquidatePrice > basePrice - lossStopForLong ) {
						// //
						// 停損出場當天要平倉前變成正獲利，就不平倉了，繼續持有。
						// ****************************************
						// 這要盯收盤，不太符合本程式精神
						// *******************
						// inHand = true;
						// continue;
						// }

						// double profit = liquidatePrice - basePrice; // 計算獲利
						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						// accuProfit += profit;
						stopProfitOpenCloseStat.enter(nextBar2.open
								- nextBar2.close);
						accuProfit += profit2;
						stopProfitStat.enter(profit2);
						// scProfit.enter(profit);
						scProfit.enter(profit2);
						// scProfitLong.enter(profit);
						scProfitLong.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						// printTurtleAction(nextBar, inHand, bull, profit,
						// daysOut,
						// true, lossStopForLong, liquidatePrice);
						printTurtleAction(nextBar, inHand, bull, profit2,
								daysOutForLong, false, -1, true,
								profitStopForLong, forceOut, liquidatePrice2,
								nextBar2, breakBar2);
					}
				}

			}
		}

		StringBuffer buf = new StringBuffer();
		String line;
		if (IS_PRINT_TURTLE_SUMMARY) {
			setAcc(scProfit.getSum());
			setProfitStat(scProfit);
			setMDD(scProfit.maxDrawDown);
			line = String
					.format(
							"acc=%.0f[多%d進,%d出][空%d進,%d出][停損%d,%d][停利%d,%d][強制盤中停損%d],%d筆交易(%dW/%dL,勝率%.3f),\nave持有天數=%.1f(共 %.0f)日曆天=%.1f(共 %.0f)交易日,ave每筆交易獲利=%.1f(%.1fW/%.1fL),\nmin持有天數=%.0f日曆天=%.0f交易日,max持有天數=%.0f日曆天=%.0f交易日,\nmax單筆獲利=%.0f,min單筆獲利=%.0f,持有天數std=%.1f日曆天=%.1f交易日,單筆獲利std=%.1f",
							scProfit.getSum(), daysInForLong, daysOutForLong,
							daysInForShort, daysOutForShort, lossStopForLong,
							lossStopForShort, profitStopForLong,
							profitStopForShort, FORCE_STOPLOSS,
							scHoldCalendarDays.getCount(), scProfit
									.getPositiveCount(), scProfit
									.getNegativeCount(), (scProfit
									.getPositiveCount() + 0.0)
									/ scProfit.getCount(), scHoldCalendarDays
									.getMean(), scHoldCalendarDays.getSum(),
							scHoldTransactionDays.getMean(),
							scHoldTransactionDays.getSum(), scProfit.getMean(),
							scProfit.getPositiveMean(), scProfit
									.getNegativeMean(), scHoldCalendarDays
									.getMin(), scHoldTransactionDays.getMin(),
							scHoldCalendarDays.getMax(), scHoldTransactionDays
									.getMax(), scProfit.getMax(), scProfit
									.getMin(), scHoldCalendarDays
									.getStandardDeviation(),
							scHoldTransactionDays.getStandardDeviation(),
							scProfit.getStandardDeviation());
			buf.append(line + "\n");
			// System.out.println(line);
			line = "出場條件:" + this.numOutTrendReverse + "次驅勢反轉出場(max="
					+ stopTrendReverseStat.getMax() + ",min="
					+ stopTrendReverseStat.getMin() + ",正獲利次數="
					+ stopTrendReverseStat.getPositiveCount() + "(平均"
					+ (int) stopTrendReverseStat.getPositiveMean() + "),負獲利次數="
					+ stopTrendReverseStat.getNegativeCount() + "(平均"
					+ (int) stopTrendReverseStat.getNegativeMean() + "))\n"
					+ "出場條件:" + this.numOutStopLoss + "次停損出場(max="
					+ stopLossStat.getMax() + ",min=" + stopLossStat.getMin()
					+ ",正獲利次數=" + stopLossStat.getPositiveCount() + "(平均"
					+ (int) stopLossStat.getPositiveMean() + "),負獲利次數="
					+ stopLossStat.getNegativeCount() + "(平均"
					+ (int) stopLossStat.getNegativeMean() + "))\n" + "出場條件:"
					+ this.numOutStopProfit + "次停利出場(max="
					+ stopProfitStat.getMax() + ",min="
					+ stopProfitStat.getMin() + ",正獲利次數="
					+ stopProfitStat.getPositiveCount() + "(平均"
					+ (int) stopProfitStat.getPositiveMean() + "),負獲利次數="
					+ stopProfitStat.getNegativeCount() + "(平均"
					+ (int) stopProfitStat.getNegativeMean() + "))\n"+
					"出場條件:"
					+ this.numOutForceStopLoss + "次盤中停損出場(max=" +
					stopForceStopLossStat.getMax()+",min="+
					stopForceStopLossStat.getMin()+
					"(平均"
					+ (int) stopForceStopLossStat.getMean() + "))"+
				    "\n";
					
			buf.append(line);
			line = "停損出場時採用<隔天收盤出場>比<隔天開盤出場>好處:最大增獲利:"
					+ stopLossOpenCloseStat.getMax() + ",最大減獲利:"
					+ stopLossOpenCloseStat.getMin() + ",增獲利次數:"
					+ stopLossOpenCloseStat.getPositiveCount() + "(平均"
					+ stopLossOpenCloseStat.getPositiveMean() + "),減獲利次數:"
					+ stopLossOpenCloseStat.getNegativeCount() + "(平均"
					+ stopLossOpenCloseStat.getNegativeMean() + ")";
			buf.append(line + "\n");
			line = "停利出場時採用<隔天開盤出場>比<隔天收盤出場>好處:最大增獲利:"
					+ stopProfitOpenCloseStat.getMax() + ",最大減獲利:"
					+ stopProfitOpenCloseStat.getMin() + ",增獲利次數:"
					+ stopProfitOpenCloseStat.getPositiveCount() + "(平均"
					+ stopProfitOpenCloseStat.getPositiveMean() + "),減獲利次數:"
					+ stopProfitOpenCloseStat.getNegativeCount() + "(平均"
					+ stopProfitOpenCloseStat.getNegativeMean() + ")";
			buf.append(line + "\n");

			Iterator<String> iter = tradeMap.keySet().iterator();
			while (iter.hasNext()) {
				String key = iter.next();
				line = key + "個數:" + tradeMap.get(key) + "\n";
				buf.append(line);
			}
			line = (String
					.format(
							"多單accLong獲利=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitLong.getSum(), scProfitLong.getCount(),
							scProfitLong.getPositiveCount(), scProfitLong
									.getNegativeCount(), (scProfitLong
									.getPositiveCount() + 0.0)
									/ scProfitLong.getCount(), scProfitLong
									.getMean(), scProfitLong.getPositiveMean(),
							scProfitLong.getNegativeMean(), scProfitLong
									.getMax(), scProfitLong.getMin(),
							scProfitLong.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String
					.format(
							"空單accShort獲利=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitShort.getSum(), scProfitShort.getCount(),
							scProfitShort.getPositiveCount(), scProfitShort
									.getNegativeCount(), (scProfitShort
									.getPositiveCount() + 0.0)
									/ scProfitShort.getCount(), scProfitShort
									.getMean(),
							scProfitShort.getPositiveMean(), scProfitShort
									.getNegativeMean(), scProfitShort.getMax(),
							scProfitShort.getMin(), scProfitShort
									.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String
					.format(
							"多單建立日accLongDayTrade獲利(開盤空、收盤補並做多)=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitLongDayTrade.getSum(), scProfitLongDayTrade
									.getCount(), scProfitLongDayTrade
									.getPositiveCount(), scProfitLongDayTrade
									.getNegativeCount(), (scProfitLongDayTrade
									.getPositiveCount() + 0.0)
									/ scProfitLongDayTrade.getCount(),
							scProfitLongDayTrade.getMean(),
							scProfitLongDayTrade.getPositiveMean(),
							scProfitLongDayTrade.getNegativeMean(),
							scProfitLongDayTrade.getMax(), scProfitLongDayTrade
									.getMin(), scProfitLongDayTrade
									.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String
					.format(
							"空單建立日accShortDayTrade獲利(開盤加倍空、收盤補一半)=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitShortDayTrade.getSum(),
							scProfitShortDayTrade.getCount(),
							scProfitShortDayTrade.getPositiveCount(),
							scProfitShortDayTrade.getNegativeCount(),
							(scProfitShortDayTrade.getPositiveCount() + 0.0)
									/ scProfitShortDayTrade.getCount(),
							scProfitShortDayTrade.getMean(),
							scProfitShortDayTrade.getPositiveMean(),
							scProfitShortDayTrade.getNegativeMean(),
							scProfitShortDayTrade.getMax(),
							scProfitShortDayTrade.getMin(),
							scProfitShortDayTrade.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String
					.format(
							"多單停損日當沖accLongClosDayTrade獲利=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitLongCloseDayTrade.getSum(),
							scProfitLongCloseDayTrade.getCount(),
							scProfitLongCloseDayTrade.getPositiveCount(),
							scProfitLongCloseDayTrade.getNegativeCount(),
							(scProfitLongCloseDayTrade.getPositiveCount() + 0.0)
									/ scProfitLongCloseDayTrade.getCount(),
							scProfitLongCloseDayTrade.getMean(),
							scProfitLongCloseDayTrade.getPositiveMean(),
							scProfitLongCloseDayTrade.getNegativeMean(),
							scProfitLongCloseDayTrade.getMax(),
							scProfitLongCloseDayTrade.getMin(),
							scProfitLongCloseDayTrade.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String
					.format(
							"空單停損日當沖accShortCloseDayTrade獲利(開盤加碼空、收盤全平)=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitShortCloseDayTrade.getSum(),
							scProfitShortCloseDayTrade.getCount(),
							scProfitShortCloseDayTrade.getPositiveCount(),
							scProfitShortCloseDayTrade.getNegativeCount(),
							(scProfitShortCloseDayTrade.getPositiveCount() + 0.0)
									/ scProfitShortCloseDayTrade.getCount(),
							scProfitShortCloseDayTrade.getMean(),
							scProfitShortCloseDayTrade.getPositiveMean(),
							scProfitShortCloseDayTrade.getNegativeMean(),
							scProfitShortCloseDayTrade.getMax(),
							scProfitShortCloseDayTrade.getMin(),
							scProfitShortCloseDayTrade.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String.format("accuProfit = %.0f", accuProfit));
			buf.append(line + "\n");
			// System.out.println(line);
			logger.info("\n" + buf.toString());
			summary = buf.toString();
		}
		return scProfit.getSum();
	}

	private static Logger loadDefaultLogger() {
		Properties logp = new Properties();
		try {
			logp.load(PriceData.class.getClassLoader().getResourceAsStream(
					"turtle/system/pt/j4util.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		PropertyConfigurator.configure(logp);

		return Logger.getRootLogger();
	}

	public static void main(String[] args) throws IOException {
		/**
		 * 使用pt的參數
		 */
		inAndOut_CONSERVATIVE = new int[][] { // 特別觀察組合
		{ 3, 16, 15, 22 } // 保守穩健系統
		};
		LOSS_STOP_RANGE_FOR_SHORT_CONSERVATIVE = new int[] { 31, 31 }; // 做空停損點數實驗區間
		LOSS_STOP_RANGE_FOR_LONG_CONSERVATIVE = new int[] { 10, 10 }; // 做多停損點數實驗區間
		PROFIT_STOP_RANGE_FOR_SHORT_CONSERVATIVE = new int[] { 10000, 10000 }; // 做空停利點數實驗區間
		PROFIT_STOP_RANGE_FOR_LONG_CONSERVATIVE = new int[] { 10000, 10000 }; // 做多停損點數實驗區間

		PriceDataStopProfit cons = new PriceDataStopProfit(
				PriceDataStopProfit.STRATEGY_CONSERVATIVE,
				DailyStopProfitExec.WTX0_PREFIX_FN
						+ DailyStopProfitExec.FN_SUFFIX,
				DailyStopProfitExec.WTX1_PREFIX_FN
						+ DailyStopProfitExec.FN_SUFFIX);

		inAndOut_POSITIVE = new int[][] { // 特別觀察組合
		{ 9, 21, 3, 5 } // 積極進取系統
		};

		LOSS_STOP_RANGE_FOR_LONG_POSITIVE = new int[] { 31, 31 }; // 做多停損點數實驗區間
		LOSS_STOP_RANGE_FOR_SHORT_POSITIVE = new int[] { 87, 87 }; // 做空停損點數實驗區間
		PROFIT_STOP_RANGE_FOR_SHORT_POSITIVE = new int[] { 10000, 10000 }; // 做空停利點數實驗區間
		PROFIT_STOP_RANGE_FOR_LONG_POSITIVE = new int[] { 10000, 10000 }; // 做多停損點數實驗區間

		PriceDataStopProfit posi = new PriceDataStopProfit(
				PriceDataStopProfit.STRATEGY_POSITIVE,
				DailyStopProfitExec.WTX0_PREFIX_FN
						+ DailyStopProfitExec.FN_SUFFIX,
				DailyStopProfitExec.WTX1_PREFIX_FN
						+ DailyStopProfitExec.FN_SUFFIX);

	}
}